﻿using System;
using System.Windows.Forms;

using Presenter;
using IView;
using DataTransferObject;
using System.Collections.Generic;
using System.Drawing;

namespace JSKE
{
    /*
     * Class cung cấp giao diện để nhập thông tin chi tiết cho 1 task
     */ 
    public partial class TaskForm : FormLang, ITaskForm
    {

        #region Attributes
        private PresenterTaskForm _presenter;
        private Task _currentEditTask;
        private Boolean _isEditing;
        private String pathToLoadSystemConfig = Application.StartupPath + @"\JSKEData.bin";
        #endregion

        #region Constructor TaskForm
        /// <summary>
        /// Initializes a new instance of the <see cref="TaskForm"/> class.
        /// </summary>
        public TaskForm()
        {
            //InitializeComponent();
            InitializeForComBoExternalConstraint();
            this.cbbPrior.SelectedIndex = 0;
            this.cbbStatus.SelectedIndex = 0;
            _presenter = new PresenterTaskForm(this, DATA_MODE);
            _currentEditTask = null;
            _isEditing = false;
             
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TaskForm"/> class.
        /// </summary>
        /// <param name="t">The t.</param>
        public TaskForm(Task t)
        {
            if (t != null)
            {
                //InitializeComponent();
                InitializeForComBoExternalConstraint();
                _presenter = new PresenterTaskForm(this, DATA_MODE);
                _presenter.PopulateTaskObjectIntoForm(t);
                _currentEditTask = t;
                _isEditing = true;
            }
            
        }

        public TaskForm(Task t, Boolean isEdit)
        {
            if (t != null)
            {
                //InitializeComponent();
                InitializeForComBoExternalConstraint();
                _presenter = new PresenterTaskForm(this, DATA_MODE);
                _presenter.PopulateTaskObjectIntoForm(t);
                _currentEditTask = t;
                _isEditing = isEdit;

            }

        }

        private void InitializeForComBoExternalConstraint()
        {

            //comBoExConstr.Items.Add(ExternalConstraints.FINISH_ON);
            comBoExConstr.Items.Add(PresenterTaskForm.ExternalConstraints.NO_CONSTRAINT);
            comBoExConstr.Items.Add(PresenterTaskForm.ExternalConstraints.FINISH_ON_OR_BEFORE);
            //comBoExConstr.Items.Add(PresenterTaskForm.ExternalConstraints.START_ON);
            comBoExConstr.Items.Add(PresenterTaskForm.ExternalConstraints.START_ON_OR_AFTER);
        }

        #endregion

        #region Properties
        /*
         * khu khu vực này cần phải chỉnh sửa lại để chuẩn hơn
         * 1. Chuyển hết thành properties
         * 2. Khai báo interface trong ITaskForm để thông tin được rõ ràng
         */ 
        

        public void SetTotalWork(int i)
        {
            this.txtRemainingTime.Text = i + "";
        }


        public void SetTaskNotes(String s)
        {
            rtbContent.Rtf = s;
        }
        /// <summary>
        /// Gets the path to save task list.
        /// </summary>
        /// <returns></returns>
        public String GetPathToSaveTaskList()
        {
            return Application.StartupPath + @"\JSKETaskList.xml";
        }
        #endregion

        #region Events

        private void btnCancelClick(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnOk_Click(object sender, EventArgs e)
        {

            saveTask();
        }

        private void saveTask()
        {
            if (txtTaskName.Text.Trim() == "")
            {
                MessageBox.Show("Please input the appropriate Name", "Important Note", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else if (int.Parse(txtRemainingTime.Text.ToString()) < int.Parse(txtMinimumTimeSplit.Text.ToString()))
            {
                MessageBox.Show("Remain Time can't be smaller than MinimumTimeSplit!", "Important Note", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                #region Creating new task
                if (!_isEditing)
                {
                    Task task = new Task(GetTaskName(),
                        this.GetPriority(),
                        this.GetTotalWork());
                    ListBox.SelectedObjectCollection items = this.listBoxTasks.SelectedItems;
                    foreach (Task t in items)
                    {
                        task.AddTaskPredecessor(t);
                    }
                    task.ScheduledStartDate = DateTime.MinValue;
                    task.ScheduledEndDate = DateTime.MinValue;
                    task.MinimumTimeSplit = int.Parse(txtMinimumTimeSplit.Text.ToString());
                    task.StartOnOrAfter = this.getStartOnOrAfter();
                    task.TaskCode = DateTime.Now.Subtract(new DateTime(1988, 11, 11, 0, 0, 0)).TotalSeconds;

                    string externalConstr = comBoExConstr.SelectedItem as string;
                    if (externalConstr != null)
                    {
                        if (externalConstr.Equals(PresenterTaskForm.ExternalConstraints.FINISH_ON_OR_BEFORE))
                        {
                            task.DueDate = dateTimePickerConstraint.Value;
                        }
                    }
                    else
                    {
                        task.DueDate = DateTime.MaxValue;
                    }
                    /**
                     * Cần hiện thực việc chuyển từ các external constraint sang các constraint về release date và duedate của task
                     */
                    task.ProjectName = ddlProjectName.SelectedText;
                    task.ProjectID = ddlProjectName.SelectedIndex;
                    task.WorkingHourID = ddlWorkingHours.SelectedIndex;
                    task.TaskStatusIndex = cbbStatus.SelectedIndex;
                    task.Notes = rtbContent.Rtf;
                    if (cbbStatus.SelectedIndex == 2)
                    {
                        task.Completed = true;
                    }
                    else
                    {
                        task.Completed = false;
                    }
                    _presenter.AddTaskToEngine(task);
                }
                #endregion

                #region Editing Task
                else
                {
                    ListBox.SelectedObjectCollection items = this.listBoxTasks.SelectedItems;
                    _currentEditTask.PredecessorIDs.Clear();
                    foreach (Task t in items)
                    {
                        if (_currentEditTask.TaskID != t.TaskID)// tranh task add chinh no
                        {
                            _currentEditTask.AddTaskPredecessor(t);
                        }
                    }
                    try
                    {
                        //_currentEditTask.TaskCode = DateTime.Now.Subtract(new DateTime(1988, 11, 11, 0, 0, 0)).TotalSeconds;
                        _presenter.UpdateTaskToEngine(_currentEditTask);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return;
                    }
                }

                #endregion

                this.Close();
            }
        }

        /// <summary>
        /// Xử lí event khi nhấn vào checkbox chọn task phải kết thúc trước task hiện tại.
        /// Chức năng này sử dụng để tạo các precedence constraints các task với nhau
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void chkBoxTasks_CheckedChanged(object sender, EventArgs e)
        {
            if (chkBoxTasks.Checked == true)
            {
                this.listBoxTasks.Enabled = true;
                this.listBoxTasks.DataSource = _presenter.GetUnconstrainedTasks();               
            }
            else
            {
                this.listBoxTasks.Enabled = true;
                this.listBoxTasks.DataSource = null;
            }
        }
        #endregion

        #region ITaskForm Members

        public string GetTaskName()
        {
            return txtTaskName.Text;
        }

        public void setStartOnOrAfter(DateTime startOnOrAfter)
        {
            if (startOnOrAfter.Equals(DateTime.MinValue))
            {
                chkStartOnOrAfter.Checked = false;
                dtpkStartOnOrAfter.Enabled = false;
            }
            else
            {
                chkStartOnOrAfter.Checked = true;
                dtpkStartOnOrAfter.Enabled = true;
                dtpkStartOnOrAfter.Value = startOnOrAfter;
            }
        }

        public void SetTaskName(string s)
        {
            this.txtTaskName.Text = s;
        }

        public string GetStartTime()
        {
            if (txtScheduledStartTime.Text.Equals("None"))
            {
                return string.Empty;
            }
            else
            {
                return txtScheduledStartTime.Text;
            }
        }

        public string GetEndTime()
        {
            if (txtScheduledEndtime.Text.Equals("None"))
            {
                return string.Empty;
            }
            else
            {
                return txtScheduledEndtime.Text;
            }
        }

        public int GetPriority()
        {
            if (cbbPrior.SelectedIndex.ToString() != "")
            {
                return int.Parse(cbbPrior.SelectedItem.ToString());
            }
            else
            {
                return -1;
            }
        }

        public void SetPriority(string s)
        {
            this.cbbPrior.SelectedItem = s;
        }

        public int GetTotalWork()
        {
            try
            {
                return int.Parse(txtRemainingTime.Text.ToString().Trim());
            }
            catch (Exception ex)
            {
                MessageBox.Show("Invalid Remaining Time", "important Notes: " + ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return 0;
            }

        }

        public string GetProjectName()
        {
            return (ddlProjectName.SelectedItem != null)?ddlProjectName.SelectedItem.ToString() : string.Empty;
        }

        public int GetProjectID()
        {
            return ddlProjectName.SelectedIndex;
        }
        public int GetWorkingHourID()
        {
            return ddlWorkingHours.SelectedIndex;
        }

        public void SetProjectName(string projectName)
        {
            if (projectName == null || projectName == "")
            {
                ddlProjectName.SelectedIndex = 0;
            }
            else
            {
                ddlProjectName.SelectedItem = projectName;
            }
        }

        public void SetWorkingHourID(int workingHourID)
        {
            if (ddlWorkingHours.Items.Count > workingHourID)
            {
                ddlWorkingHours.SelectedIndex = workingHourID;
            }
        }

        public void SetMinimumTimeSplit(int minimumTimeSplit)
        {
            txtMinimumTimeSplit.Text = Convert.ToString(minimumTimeSplit);
        }

        public int GetMinimumTimeSplit()
        {
            return int.Parse(txtMinimumTimeSplit.Text.ToString());
        }
        public void SetWorkingHourName(List<String> workingHourName)
        {
            for (int i = 0; i < workingHourName.Count; i++)
            {
                ddlWorkingHours.Items.Add(workingHourName[i]);
            }
            if (workingHourName.Count > 0)
            {
                ddlWorkingHours.SelectedIndex = 0;
            }
        }

        public void SetProjectNamesForDDL(List<String> projectName)
        {
            for (int i = 0; i < projectName.Count; i++)
            {
                ddlProjectName.Items.Add(projectName[i]);
            }
            if (projectName.Count > 0)
            {
                ddlProjectName.SelectedIndex = 0;
            }
        }

        public int GetActualWork()
        {
            if (txtActualWork.Text.Equals(string.Empty))
            {
                return 0;
            }
            else
            {
                return int.Parse(txtActualWork.Text);
            }
        }

        public void SetActualWork(int actualMinuteWork)
        {
            txtActualWork.Text = actualMinuteWork + "";
        }


        public void SetRemainingTime(Double remainTime)
        {
            txtRemainingTime.Text = Convert.ToString(remainTime);
        }

        public int GetRemainingTime()
        {
            return int.Parse(txtRemainingTime.Text.ToString());
        }

        public String GetPathToLoadSystemConfig()
        {
            return pathToLoadSystemConfig;
        }

        public void SetStartDate(DateTime startDateTime)
        {
            if (startDateTime == DateTime.MinValue)
            {
                txtScheduledStartTime.Text = "None";
            }
            else
            {
                txtScheduledStartTime.Text = startDateTime.Date.ToString();
            }
        }

        public void SetEndDate(DateTime endDateTime)
        {
            if (endDateTime == DateTime.MinValue)
            {
                txtScheduledEndtime.Text = "None";
            }
            else
            {
                txtScheduledEndtime.Text = endDateTime.Date.ToString();
            }
        }

        public void SetTaskListPrecedence(List<int> taskPrecedenceIDs)
        {
            if (taskPrecedenceIDs.Count > 0)
            {
                chkBoxTasks.Checked = true;
                listBoxTasks.DataSource = _presenter.GetUnconstrainedTasks();
                List<Task> sourceTasks = listBoxTasks.DataSource as List<Task>;
                for (int j = 0; j < sourceTasks.Count; j++)
                {
                    int index = taskPrecedenceIDs.IndexOf(sourceTasks[j].TaskID);
                    if (index >= 0)
                    {
                        listBoxTasks.SelectedIndices.Add(index);
                    }
                }
            }
        }

        public int GetStatusID()
        {
            return this.cbbStatus.SelectedIndex;
        }

        public void SetStatusID(int theIndex)
        {
            this.cbbStatus.SelectedIndex = theIndex;
        }


        public DateTime GetDueDate()
        {
            String exconstr = comBoExConstr.SelectedItem as string;
            if (!string.IsNullOrEmpty(exconstr))
            {
                if (exconstr.Equals(PresenterTaskForm.ExternalConstraints.FINISH_ON_OR_BEFORE))
                {
                    return dateTimePickerConstraint.Value;
                }
            }
            else
            {
                return DateTime.MaxValue;
            }
            return DateTime.MaxValue;
        }

        public string GetNotes()
        {
            return rtbContent.Rtf;
        }

        public void SetTaskExternalConstraint(String constraintName, DateTime constraintDate)
        {
            this.comBoExConstr.SelectedItem = constraintName;
            if (constraintDate.Year< 9000)
            {
                dateTimePickerConstraint.Value = constraintDate;
            }
        }

        public DateTime getStartOnOrAfter()
        {
            if (chkStartOnOrAfter.Checked)
            {
                return dtpkStartOnOrAfter.Value;
            }
            else
            {
                return DateTime.MinValue;
            }
        }

        #endregion

        public void setFocusOnMinSplit(Boolean isFocus)
        {
            if (isFocus)
            {
                this.txtMinimumTimeSplit.SelectAll();
                this.txtMinimumTimeSplit.Focus();              
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            saveTask();
        }

        private void cbkCompleted_CheckedChanged(object sender, EventArgs e)
        {
            if (cbkCompleted.Checked)
            {
                cbbStatus.SelectedIndex = 2;
            }
        }


        private void btLeft_Click(object sender, EventArgs e)
        {
            btLeft.Checked = false;
            btCenter.Checked = false;
            btRight.Checked = false;
            ToolStripButton myButton = (ToolStripButton)sender;
            myButton.Checked = true;
            rtbContent.SelectionAlignment = (HorizontalAlignment)int.Parse(myButton.Tag.ToString());
        }

        private void btnFont_Click(object sender, EventArgs e)
        {
            FontDialog fDlg = new FontDialog();
            fDlg.Font = rtbContent.SelectionFont;
            fDlg.Color = rtbContent.SelectionColor;

            fDlg.ShowColor = true;
            if (fDlg.ShowDialog() == DialogResult.Cancel) return;
            rtbContent.SelectionFont = fDlg.Font;
            rtbContent.SelectionColor = fDlg.Color;
        }

        private void btnBullet_Click(object sender, EventArgs e)
        {
            rtbContent.SelectionBullet = btnBullet.Checked;
        }

        private void btnBIndent_DropDownClosed(object sender, EventArgs e)
        {
            rtbContent.BulletIndent = 5 * int.Parse(txtIndent.Text);
            rtbContent.SelectionIndent = 5 * int.Parse(txtAlignment.Text);
        }

        private void txtIndent_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (char.IsDigit(e.KeyChar) || e.KeyChar == 8) return;
            e.KeyChar = '\0';
        }

        private void richTextBox1_SelectionChanged(object sender, EventArgs e)
        {
            ToolStripButton myButton;
            switch (rtbContent.SelectionAlignment)
            {
                case HorizontalAlignment.Center:
                    myButton = btCenter;
                    break;
                case HorizontalAlignment.Left:
                    myButton = btLeft;
                    break;
                default:
                    myButton = btRight;
                    break;
            }
            if (!myButton.Checked) myButton.PerformClick();
            btnBullet.Checked = rtbContent.SelectionBullet;
            if (btnBullet.Checked) txtIndent.Text = "" + rtbContent.SelectionHangingIndent / 5;

            txtAlignment.Text = "" + rtbContent.SelectionIndent / 5;
            btnBold.Checked = (rtbContent.SelectionFont != null) && rtbContent.SelectionFont.Bold;
            btnItalic.Checked = (rtbContent.SelectionFont != null) && rtbContent.SelectionFont.Italic;
            btnUnderline.Checked = (rtbContent.SelectionFont != null) && rtbContent.SelectionFont.Underline;
        }

        private void btnWordWrap_Click(object sender, EventArgs e)
        {
            rtbContent.WordWrap = btnWordWrap.Checked;
        }

        private void btnBold_Click(object sender, EventArgs e)
        {
            FontStyle style = rtbContent.SelectionFont.Style;
            style = btnBold.Checked ? style | FontStyle.Bold : style & ~FontStyle.Bold;
            style = btnItalic.Checked ? style | FontStyle.Italic : style & ~FontStyle.Italic;
            style = btnUnderline.Checked ? style | FontStyle.Underline : style & ~FontStyle.Underline;
            Font f = new Font(rtbContent.SelectionFont, style);
            rtbContent.SelectionFont = f;
        }

        private void mnRed_Click(object sender, EventArgs e)
        {
            rtbContent.SelectionColor = ((ToolStripMenuItem)sender).ForeColor;
        }

        private void chkStartOnOrAfter_CheckedChanged(object sender, EventArgs e)
        {
            if (chkStartOnOrAfter.Checked)
            {
                dtpkStartOnOrAfter.Enabled = true;
            }
            else
            {
                dtpkStartOnOrAfter.Enabled = false;
            }
        }
    }
}
